package com.threeti.mecool.web.controller;

import com.threeti.mecool.core.application.acl.EmployeeService;
import com.threeti.mecool.core.application.acl.UserService;
import com.threeti.mecool.core.application.message.MessageService;
import com.threeti.mecool.core.application.message.SystemMessageService;
import com.threeti.mecool.core.domain.model.acl.User;
import com.threeti.mecool.core.domain.model.message.MobileMessage;
import com.threeti.mecool.core.domain.model.message.MobileMessage.Priority;
import com.threeti.mecool.core.domain.model.message.SystemMessage;
import com.threeti.mecool.core.domain.model.project.Project;
import com.threeti.mecool.core.domain.model.project.ProjectEmployee;
import com.threeti.mecool.core.infrastructure.persistence.acl.UserRepository;
import com.threeti.mecool.core.infrastructure.persistence.message.MobileMessageRepository;
import com.threeti.mecool.core.infrastructure.persistence.message.SystemMessageRepository;
import com.threeti.mecool.core.infrastructure.persistence.project.ProjectRepository;
import com.threeti.mecool.framework.util.Lists;
import com.threeti.mecool.framework.util.Maps;
import com.threeti.mecool.framework.util.PageHandler;
import com.threeti.mecool.web.util.WebResponse;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.*;


@Controller
@RequestMapping("/message")
public class MessageController {

    public static final Logger logger = LoggerFactory.getLogger(MessageController.class);

    @Autowired
    EmployeeService employeeService;

    @Autowired
    UserService userService;

    @Autowired
    ProjectRepository projectRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    MessageService messageService;

    @Autowired
    SystemMessageService systemMessageService;

    @Autowired
    MobileMessageRepository mobileMessageRepository;

    @Autowired
    SystemMessageRepository systemMessageRepository;

    @SuppressWarnings({"rawtypes", "unchecked"})
    @RequestMapping(value = "/pushMessageForm.html")
    public void pushMessageForm(Map modelMap) throws JsonGenerationException, JsonMappingException, IOException {
        List<ProjectEmployee> employees = employeeService.findSubordinateEmployeesOfUser(userService.getUserFromSession());

        Map<Long, List> employeeMap = new HashMap<Long, List>();
        for (ProjectEmployee projectEmployee : employees) {
            if (employeeMap.containsKey(projectEmployee.getProject().getId())) {
                employeeMap.get(projectEmployee.getProject().getId()).add(projectEmployee);
            } else {
                List list = Lists.newArrayList();
                list.add(projectEmployee);
                employeeMap.put(projectEmployee.getProject().getId(), list);
            }
        }

        List<Map> projectEmployees = Lists.newArrayList();

        Set<Long> projectCodes = employeeMap.keySet();
        Iterator<Long> it = projectCodes.iterator();
        while (it.hasNext()) {
            Long id = it.next();
            Project project = projectRepository.findOne(id);

            Map e = Maps.newHashMap();
            e.put("projectName", project.getName());

            List<ProjectEmployee> employeeList = employeeMap.get(id);
            List<Map> list = Lists.newArrayList();
            for (ProjectEmployee employee : employeeList) {
                Map emp = Maps.newHashMap();
                User user = userRepository.findByEmployeeEmpId(employee.getEmpId());
                if (user == null) {
                    continue;
                }
                emp.put("loginName", user.getLoginName());
                emp.put("empName", employee.getEmpName());
                list.add(emp);
            }
            e.put("employees", list);
            projectEmployees.add(e);
        }
        ObjectMapper mapper = new ObjectMapper();
        modelMap.put("projectEmployees", mapper.writeValueAsString(projectEmployees));
    }


    /**
     * @param modelMap
     * @param head
     * @param body
     * @param priority
     * @param receivers
     * @return
     * @author Yuqi Chou
     * @version Aug 1, 2012  4:09:34 PM
     */
    @SuppressWarnings({"rawtypes"})
    @RequestMapping(value = "/pushMessage.html")
    public String pushMessage(Map modelMap, String head, String body, String priority, String receivers) {
        try {
            String[] receiverArray = receivers.split(";");
            int total = 0;
            int success = 0;
            int failed = 0;
            for (String receiver : receiverArray) {
                if (!StringUtils.hasText(receiver)) {
                    continue;
                }
                total++;
                try {
                    MobileMessage msg = new MobileMessage(head,
                            body,
                            receiver,
                            userService.getUserFromSession().getLoginName(),
                            Priority.valueOf(priority));
                    messageService.send(msg);
                    systemMessageService.send(msg.getCreator(), msg.getReceiver(), msg.getHead(), msg.getBody());
                    success++;
                } catch (Exception e) {
                    failed++;
                    logger.error("", e);
                }
            }

            StringBuffer sb = new StringBuffer();
            sb.append("发送总数:");
            sb.append(total);
            sb.append("\n");
            sb.append("成功:");
            sb.append(success);
            sb.append("\n");
            sb.append("失败:");
            sb.append(failed);


            WebResponse.newInstance()
                    .putExtraData("sendResults", sb.toString())
                    .buildModelMapData(modelMap);
        } catch (Exception e) {
            logger.error("", e);
            WebResponse.newInstance().setExceptionMsg(e).buildModelMapData(modelMap);
        }

        return WebResponse.GLOBAL_SUBMIT_CALLBACK_PAGE;
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    @RequestMapping(value = "/pushMessageListData.html")
    public void pushMessageListData(Map modelMap, Pageable pageable) {
        User user = userService.getUserFromSession();

        pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), Sort.Direction.DESC, "createdOn");
        Page messages = mobileMessageRepository.findByCreator(user.getLoginName(), pageable);
        PageHandler p = new PageHandler(pageable.getPageNumber(),
                Long.valueOf(messages.getTotalElements()).intValue(),
                pageable.getPageSize(),
                messages.getContent());
        modelMap.put("page", p);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    @RequestMapping(value = "/receiptListData.html")
    public void receiptListData(Map modelMap, Pageable pageable) {
        User user = userService.getUserFromSession();
        pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), Sort.Direction.DESC, "createdOn");
        Page messages = mobileMessageRepository.findByCreatorAndReceivedOnIsNotNull(user.getLoginName(), pageable);
        PageHandler p = new PageHandler(pageable.getPageNumber(),
                Long.valueOf(messages.getTotalElements()).intValue(),
                pageable.getPageSize(),
                messages.getContent());
        modelMap.put("page", p);
    }


    @ResponseBody
    @RequestMapping(value = "/fetchNotifications.html")
    public Object fetchNotifications() {
        WebResponse res = WebResponse.newInstance();
        try {
            User user = userService.getUserFromSession();
            res.putExtraData("msgNum", systemMessageRepository.countUnReadSysMessageNum(user.getLoginName()).intValue());
        } catch (Exception e) {
            logger.error("", e);
            res.putExtraData("msgNum", 0);
        }
        return res;
    }


    @SuppressWarnings({"rawtypes", "unchecked"})
    @RequestMapping(value = "/sysMessageListData.html")
    public void sysMessageListData(Map modelMap, Pageable pageable) {
        User user = userService.getUserFromSession();

        pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), Sort.Direction.DESC, "createdOn");
        Page messages = systemMessageRepository.findByReceiver(user.getLoginName(), pageable);
        PageHandler p = new PageHandler(pageable.getPageNumber(),
                Long.valueOf(messages.getTotalElements()).intValue(),
                pageable.getPageSize(), messages.getContent());

        try {
            List<SystemMessage> data = (List) p.getData();
            if (data.size() > 0) {
                long[] messageIdArray = new long[data.size()];
                int index = 0;
                for (SystemMessage systemMessage : data) {
                    messageIdArray[index] = systemMessage.getId();
                    index++;
                }
                systemMessageService.markMessagesAsRead(messageIdArray);
            }

        } catch (Exception e) {
            logger.error("", e);
        }

        modelMap.put("page", p);
    }


}
